//
//  hd_fs_operation.h
//  Draco
//
//  Created by Liu Dafan on 12-2-20.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#ifndef Draco_hd_fs_operation_h
#define Draco_hd_fs_operation_h

#include <map>
#include <string>
#include "hdfs_client.h"
#include "common.h"

const uint32_t MAX_TABLE_NAME = 128;
class HadoopFSOperation
{
public:
    HadoopFSOperation(const char* dirtable, const char* filetable);
    virtual ~HadoopFSOperation();
    
    HResult GetSubdirInfo(DIR_ID parentID, const std::string& dirName, OUT DIR_INFO& dirInfo);
    
    HResult GetSubdirInfos(DIR_ID parentID, OUT std::vector<DIR_INFO>& dirInfos);
    
    HResult GetSubfileInfo(DIR_ID parentID, const std::string& fileName, OUT FILE_INFO& fileInfo); //last version

    HResult GetSubfileInfo(DIR_ID parentID, const std::string& fileName, uint32_t version, OUT FILE_INFO& fileInfo); //given version
    
    HResult GetSubfileInfo(DIR_ID parentID, const std::string& fileName, OUT std::vector<FILE_INFO>& fileInfos); //all versions
    
    HResult GetSubfileInfos(DIR_ID parentID, OUT std::vector<FILE_INFO>& fileInfos);
    
    HResult ReadFile(const FILE_INFO& sourceInfo, uint64_t offset, OUT int8_t* buf, size_t readCount, OUT size_t& actualReadCount);
    
    /* Write Operations */
    HResult CreateNewDir(DIR_ID parentID, const std::string& newDirName, OUT DIR_INFO& newDirInfo);
    
    HResult CreateLinkDir(DIR_ID parentID, const std::string& newDirName, DIR_ID sourceID, OUT DIR_INFO& newDirInfo);
    
    HResult RenameDir(DIR_ID parentID, const std::string& orgDirName, const std::string& newDirName, OUT DIR_INFO& newDirInfo);
    
    HResult DeleteDir(DIR_ID parentID, const std::string& orgDirName); // in recursion 

    HResult RecoverDir(DIR_ID parentID, const std::string& orgDirName);

    HResult CreateNewFile(DIR_ID parentID, const std::string& newFileName, const int8_t* buf, size_t bufLen, OUT FILE_INFO& newFileInfo);
    
    HResult CreateNewFile(DIR_ID parentID, const std::string& newFileName, const std::string& localFileName, OUT FILE_INFO& newFileInfo);
    
    HResult CreateLinkFile(DIR_ID parentID, const std::string& newFileName, const FILE_INFO& sourceInfo, OUT FILE_INFO& newFileInfo);
    
    HResult RenameFile(DIR_ID parentID, const std::string& orgFileName, const std::string& newFileName, OUT FILE_INFO& newFileInfo);
    
    HResult DeleteFile(DIR_ID parentID, const std::string& orgFileName);

    HResult RecoverFile(DIR_ID parentID, const std::string& orgFileName);

protected:
    HResult DeleteDir(DIR_INFO& dirinfo, bool recover = false);
    HResult DeleteFile(FILE_INFO& fileinfo, bool recover = false);
    
    HResult GetNewDirId(USER_ID userid, DIR_ID& dirid);
    HResult GetCurrentFileName(USER_ID userid, std::string& filename);
    std::string GetNewFileName(USER_ID userid);
private:

    std::string    _dirTable;
    std::string    _fileTable;
    uint64_t _maxfilelength;
    
    std::set<USER_ID> _users;
    std::map<USER_ID, std::string> _filemap;
    pthread_mutex_t   _lock;
};

#endif
